#include "multiscreen.h"
#include <qDebug>
#include <QDir>
#include <QFileInfo>

#define _HU_SERVER_IP    "192.168.2.100"
#define _HU_SERVER_PORT   10005

std::unique_ptr<MultiScreen> MultiScreen::multiScreenInstance = nullptr;

std::unique_ptr<MultiScreen>& MultiScreen::getInstance()
{
    static std::once_flag flag;
    std::call_once(flag, []() {
        multiScreenInstance = std::make_unique<MultiScreen>();
    });
    return multiScreenInstance;
}

MultiScreen::MultiScreen(){
    qDebug() << "MultiScreen::MultiScreen()";

    timerCalling = new QTimer(nullptr);
    connect(timerCalling, &QTimer::timeout, this, &MultiScreen::CallingTimerUpdater);

    timerMusic = new QTimer(nullptr);
    connect(timerMusic, &QTimer::timeout, this, &MultiScreen::MusicTimerUpdater);
}

MultiScreen::~MultiScreen(){
    if (httpServer) {
        delete httpServer;
        httpServer = nullptr;
    }
    if (isConnected) {
        socket.disconnectFromHost();
        socket.waitForDisconnected(1000);
        socket.close();
        isConnected = false;
    }
    if(timerCalling){
        delete timerCalling;
        timerCalling = nullptr;
    }
    if(timerMusic){
        delete timerMusic;
        timerMusic = nullptr;
    }
}

bool MultiScreen::startHttpServer()
{
    if (!isServerRunning) {
        httpServer = new QHttpServer(nullptr);

        httpServer->route("/download/<arg>", [](const QString &filePath) {
            QString fullPath = QDir::currentPath() + "/download/" + filePath;
            QFileInfo fileInfo(fullPath);

            if (fileInfo.exists() && fileInfo.isFile()) {
                QFile file(fullPath);
                if (file.open(QIODevice::ReadOnly)) {
                    QByteArray fileData = file.readAll();
                    file.close();

                    QHttpServerResponse response(fileData);
                    // 设置 Content-Disposition 头，告知浏览器将响应内容作为附件下载
                    response.setHeader("Content-Disposition", QString("attachment; filename=\"%1\"").arg(fileInfo.fileName()).toUtf8());
                    // 设置 Content-Type 头，根据文件扩展名设置合适的 MIME 类型
                    QString fileExtension = fileInfo.suffix().toLower();
                    if (fileExtension == "jpg" || fileExtension == "jpeg") {
                        response.setHeader("Content-Type", "image/jpeg");
                    } else if (fileExtension == "png") {
                        response.setHeader("Content-Type", "image/png");
                    }
                    response.setHeader("Connection", "close");
                    return response;
                }
            }
            return QHttpServerResponse(QHttpServerResponse::StatusCode::NotFound);
        });

        quint16 port = httpServer->listen(QHostAddress::Any, 8000);

        if (port > 0) {
            qDebug() << "HTTP server started on port" << port;
            isServerRunning = true;
        } else {
            qDebug() << "Failed to start HTTP server";
        }
    } else {
        if (httpServer) {
            delete httpServer;
            httpServer = nullptr;
        }
        qDebug() << "HTTP server stopped";
        isServerRunning = false;
    }

    return isServerRunning;
}

bool MultiScreen::connectHuServer()
{
    if (isConnected) {
        socket.disconnectFromHost();
        if (socket.state() == QAbstractSocket::UnconnectedState || socket.waitForDisconnected(1000)) {
            isConnected = false;
            socket.close();
            qDebug() << "已断开与服务器的连接";
        }
    } else {
        socket.connectToHost(_HU_SERVER_IP, _HU_SERVER_PORT);
        if (socket.waitForConnected(3000)) {
            isConnected = true;
            qDebug() << "已成功连接到服务器";
        } else {
            qDebug() << "无法连接到服务器";
        }
    }
    return isConnected;
}

void MultiScreen::MusicTimerUpdater()
{
    MusicSeconds++;
    qDebug() << "MusicTimerUpdater";
    if(MusicSeconds <= MusicSecondsTotal)
    {
        qDebug() << "MusicTimerUpdater <<<<<<<<<<";
        QTime time(0, 0, 0);
        time = time.addSecs(MusicSeconds);
        QString timeText = time.toString("mm:ss");

        MusicjsonObject["position"] = MusicSeconds; // 整形: 当前播放时间

        QJsonDocument jsonDoc(MusicjsonObject);
        QByteArray jsonBytes = jsonDoc.toJson(QJsonDocument::Compact);

        QByteArray frameHeader = QByteArray::fromHex("FF5AFFA5");
        QByteArray frameTail = QByteArray::fromHex("FFA5FF5A");
        QByteArray message = frameHeader + jsonBytes + frameTail;

        if (isConnected && socket.state() == QAbstractSocket::ConnectedState) {
            socket.write(message);
            socket.waitForBytesWritten();
        } else {
            qDebug() << "send error";
            socket.close();
            isPlaying = false;
            timerMusic->stop();
            isConnected = false;
        }
        emit MusicTimerSignal(isPlaying, isConnected, timeText);
    }
    else
    {
        qDebug() << "MusicTimerUpdater ++++++++++++++++";
        timerMusic->stop();
        MusicSeconds = 0;

        QTime time(0, 0, 0);
        time = time.addSecs(MusicSeconds);
        QString timeText = time.toString("mm:ss");

        isPlaying = false;
        MusicjsonObject["status"] = 0;           // 整形: 当前播放状态 0，暂停。1 播放

        QJsonDocument jsonDoc(MusicjsonObject);
        QByteArray jsonBytes = jsonDoc.toJson(QJsonDocument::Compact);

        QByteArray frameHeader = QByteArray::fromHex("FF5AFFA5");
        QByteArray frameTail = QByteArray::fromHex("FFA5FF5A");

        QByteArray message = frameHeader + jsonBytes + frameTail;

        if (isConnected && socket.state() == QAbstractSocket::ConnectedState) {
            socket.write(message);
            socket.waitForBytesWritten();
        } else {
            qDebug() << "send error";
            isPlaying = false;
            timerMusic->stop();
            isConnected = false;
        }

        emit MusicTimerSignal(isPlaying, isConnected, timeText);
    }
}

void MultiScreen::sendPackets(int number, int status)
{
    if (number == 0)
    {
        MusicSecondsTotal = 18;
        MusicjsonObject["type"] = 1;              // 整数：1 歌曲；2 通话
        MusicjsonObject["title"] = "Alice";       // 字符串：歌曲标题
        MusicjsonObject["artist"] = "艺术家";      // 字符串：艺术家
        MusicjsonObject["album"] = "专辑";         // 字符串：专辑名称
        MusicjsonObject["format"] = 1;            // 整形：JPEG0 x01、PNG 0x02
        CalljsonData["size"] =  10000;            // 整形：图片文件的大小,单位字节
        MusicjsonObject["download"] = "192.168.2.99:8000/download/music1.jpg";
    }
    else
    {
        MusicSecondsTotal = 20;
        MusicjsonObject["type"] = 1;              // 整数：1 歌曲；2 通话
        MusicjsonObject["title"] = "Lily";        // 字符串：歌曲标题
        MusicjsonObject["artist"] = "艺术家";      // 字符串：艺术家
        MusicjsonObject["album"] = "专辑";         // 字符串：专辑名称
        MusicjsonObject["format"] = 1;           // 整形：JPEG0 x01、PNG 0x02
        CalljsonData["size"] =  10000;            // 整形：图片文件的大小,单位字节
        MusicjsonObject["download"] = "192.168.2.99:8000/download/music2.jpg";
    }
    MusicjsonObject["duration"] = MusicSecondsTotal;        // 整形：歌曲总时长，单位秒
    MusicjsonObject["position"] = MusicSeconds; // 整形: 当前播放时间
    MusicjsonObject["status"] = status;           // 整形: 当前播放状态 0，暂停。1 播放

    QJsonDocument jsonDoc(MusicjsonObject);
    QByteArray packetData = jsonDoc.toJson(QJsonDocument::Compact);

    QByteArray frameHeader = QByteArray::fromHex("FF5AFFA5");
    QByteArray frameTail   = QByteArray::fromHex("FFA5FF5A");
    QByteArray message     = frameHeader + packetData + frameTail;

    if (isConnected && socket.state() == QAbstractSocket::ConnectedState) {
        socket.write(message);
        socket.waitForBytesWritten();
    } else {
        qDebug() << "无法发送数据包";
        isPlaying = false;
        timerMusic->stop();
        isConnected = false;
    }
    emit MusicTimerSignal(isPlaying, isConnected, "00:00");
    qDebug() << "sendPackets";
}

bool MultiScreen::playMusic()
{
    if (!isConnected) {
        isPlaying = false;
    } else {
        if (isPlaying) {
            timerMusic->stop();
            isPlaying = false;
            sendPackets((MusicIndex % MusicNumberMax), 0);
        } else {
            isPlaying = true;
            sendPackets((MusicIndex % MusicNumberMax), 1);
            timerMusic->start(1000);
        }
        qDebug() << "playMusic";
    }
    return isPlaying;
}

bool MultiScreen::nextMusic()
{
    if (!isConnected) {
        isPlaying = false;
    } else {
        if (isPlaying) {
            timerMusic->stop();
            MusicIndex++;
            MusicSeconds = 0;
            sendPackets((MusicIndex % MusicNumberMax), 1);
            timerMusic->start(1000);
        }
    }
    return isPlaying;
}

void MultiScreen::CallingDataSend(QJsonObject& json)
{
    QJsonDocument jsonDoc(json);
    QByteArray jsonBytes = jsonDoc.toJson(QJsonDocument::Compact);

    QByteArray frameHeader = QByteArray::fromHex("FF5AFFA5");
    QByteArray frameTail = QByteArray::fromHex("FFA5FF5A");

    QByteArray message = frameHeader + jsonBytes + frameTail;

    if (isConnected && socket.state() == QAbstractSocket::ConnectedState) {
        socket.write(message);
        socket.waitForBytesWritten();
    } else {
        socket.close();
        isCalling = false;
        timerCalling->stop();
        isConnected = false;
        emit CallingTimerSignal(0xff, " ");
    }
    qDebug() << "CallingDataSend";
}

void MultiScreen::CallingTimerUpdater()
{
    QTime time(0, 0, 0);
    QString timeText;

    switch (CallStatus) {
    case CALL_IDLE:  // 空闲状态

        timerCalling->stop();

        CalljsonData["type"] = 2;               // 整数：1 歌曲；2 通话
        CalljsonData["time"] = 0;               // 整数：当前通话时长
        CalljsonData["status"] = 0;             // 整数：描述当前状态,0 空闲，1 来电，2 通话中，3 保持，4挂断

        CallingDataSend(CalljsonData);

        emit CallingTimerSignal(0, " ");
        break;

    case CALL_INCOMING: // 拨打电话状态
        timerCalling->stop();
        emit CallingTimerSignal(1, " ");
        CallStatus = CALL_RING;

        CalljsonData["type"] = 2;               // 整数：1 歌曲；2 通话
        CalljsonData["name"] = "周杰伦";         // 字符串：联系人姓名
        CalljsonData["contact"] = "13851885188";// 字符串：联系电话
        CalljsonData["format"] =  1;            // 整形：JPEG0 x01、PNG 0x02
        CalljsonData["size"] =  10000;          // 整形：图片文件的大小,单位字节
        CalljsonData["download"] = "192.168.2.99:8000/download/call1.jpg";
        CalljsonData["time"] = 0;               // 整数：当前通话时长
        CalljsonData["status"] = 1;             // 整数：描述当前状态,0 空闲，1 来电，2 通话中，3 保持，4挂断

        qDebug() << "++++++++CALL_INCOMING+++++++++++++";
        CallingDataSend(CalljsonData);

        timerCalling->start(3000);
        break;

    case CALL_RING: // 正在振铃
        timerCalling->stop();
        emit CallingTimerSignal(2, " ");
        CallStatus = CALL_ACTIVE;

        CalljsonData["type"] = 2;               // 整数：1 歌曲；2 通话
        CalljsonData["name"] = "周杰伦";         // 字符串：联系人姓名
        CalljsonData["contact"] = "13851885188";// 字符串：联系电话
        CalljsonData["format"] =  1;            // 整形：JPEG0 x01、PNG 0x02
        CalljsonData["size"] =  10000;          // 整形：图片文件的大小,单位字节
        CalljsonData["download"] = "192.168.2.99:8000/download/call1.jpg";
        CalljsonData["time"] = 0;               // 整数：当前通话时长
        CalljsonData["status"] = 2;             // 整数：描述当前状态,0 空闲，1 来电，2 通话中，3 保持，4挂断

        qDebug() << "++++++++CALL_RING+++++++++++++";
        CallingDataSend(CalljsonData);

        timerCalling->start(3000);
        break;

    case CALL_ACTIVE:  // 正在通话中
        timerCalling->stop();
        elapsedSeconds++;
        time = time.addSecs(elapsedSeconds);
        timeText = time.toString("mm:ss");

        emit CallingTimerSignal(3, timeText);
        CallStatus = CALL_ACTIVE;

        CalljsonData["type"] = 2;               // 整数：1 歌曲；2 通话
        CalljsonData["name"] = "周杰伦";         // 字符串：联系人姓名
        CalljsonData["contact"] = "13851885188";// 字符串：联系电话
        CalljsonData["format"] =  1;            // 整形：JPEG0 x01、PNG 0x02
        CalljsonData["size"] =  10000;          // 整形：图片文件的大小,单位字节
        CalljsonData["download"] = "192.168.2.99:8000/download/call1.jpg";
        CalljsonData["time"] = elapsedSeconds;  // 整数：当前通话时长
        CalljsonData["status"] = 3;             // 整数：描述当前状态,0 空闲，1 来电，2 通话中，3 保持，4挂断

        qDebug() << "++++++++CALL_ACTIVE+++++++++++++";
        CallingDataSend(CalljsonData);

        timerCalling->start(1000);
        break;

    case CALL_HELD:
        emit CallingTimerSignal(4, " ");
        CallStatus = CALL_HELD;

        CalljsonData["type"] = 2;               // 整数：1 歌曲；2 通话
        CalljsonData["name"] = "周杰伦";         // 字符串：联系人姓名
        CalljsonData["contact"] = "13851885188";// 字符串：联系电话
        CalljsonData["format"] =  1;            // 整形：JPEG0 x01、PNG 0x02
        CalljsonData["size"] =  10000;          // 整形：图片文件的大小,单位字节
        CalljsonData["download"] = "192.168.2.99:8000/download/call1.jpg";
        CalljsonData["time"] = elapsedSeconds;  // 整数：当前通话时长
        CalljsonData["status"] = 4;             // 整数：描述当前状态,0 空闲，1 来电，2 通话中，3 保持，4挂断
        CallingDataSend(CalljsonData);

        break;

    case CALL_TERMINATED:
        timerCalling->stop();
        emit CallingTimerSignal(5, " ");
        CallStatus = CALL_IDLE;

        CalljsonData["type"] = 2;               // 整数：1 歌曲；2 通话
        CalljsonData["name"] = "周杰伦";         // 字符串：联系人姓名
        CalljsonData["contact"] = "13851885188";// 字符串：联系电话
        CalljsonData["format"] =  1;            // 整形：JPEG0 x01、PNG 0x02
        CalljsonData["size"] =  10000;          // 整形：图片文件的大小,单位字节
        CalljsonData["download"] = "192.168.2.99:8000/download/call1.jpg";
        CalljsonData["time"] = 0;               // 整数：当前通话时长
        CalljsonData["status"] = 5;             // 整数：描述当前状态,0 空闲，1 来电，2 通话中，3 保持，4挂断

        qDebug() << "++++++++CALL_ACTIVE+++++++++++++";
        CallingDataSend(CalljsonData);

        timerCalling->start(1000);
        break;

    default:
        break;
    }
}

bool MultiScreen::callOut()
{
    if (!isConnected) {
        return false;
    } else {
        if (!isCalling) {
            isCalling = true;
            elapsedSeconds = 0;
            CallStatus = CALL_INCOMING;
            timerCalling->start(1000);
        } else {
            isCalling = false;
            CallStatus = CALL_TERMINATED;
            timerCalling->stop();
            CallingTimerUpdater();
        }
    }
    return isCalling;
}
